/*
 * -------------------------------------------------------------------------
 * 文件操作工具
 * -------------------------------------------------------------------------
 * 默认不引入日志管理器，可在node环境下使用
 * 因无法使用electron，所以日志管理器无法使用
 */

const fs   = require('fs');
const path = require('path');

/*日志管理器*/
let logger;

/**
 * 引入日志管理器
 */
function requireLogger () {
    logger = require('../../src/logger');
}

/**
 * 卸载日志管理器
 */
function unrequireLogger () {
    logger = null;
}

/**
 * 删除文件和文件夹
 * @param filePath 文件和文件夹
 */
function delFiles (filePath) {
    /*路径不存在*/
    if (!fs.existsSync(filePath)) {
        return logError(`file does not exist : ${filePath}`);
    }
    
    /*文件类型 直接删除*/
    if (fs.statSync(filePath).isFile()) {
        fs.unlinkSync(filePath);
        return logInfo(`delete file : ${filePath}`);
    }
    
    /*符号连接文件 直接删除*/
    if (fs.statSync(filePath).isSymbolicLink()) {
        fs.unlinkSync(filePath);
        return logInfo(`delete symbolic link : ${filePath}`);
    }
    
    /*目录*/
    if (fs.statSync(filePath).isDirectory()) {
        /*递归删除文件*/
        fs.readdirSync(filePath).forEach(file => {
            return delFiles(path.resolve(filePath, file));
        });
        
        /*删除目录*/
        fs.rmdirSync(filePath);
        return logInfo(`delete directory : ${filePath}`);
    }
    
    /*其他文件 不支持删除*/
    return logError(`delete not supported : ${filePath}`);
}

/**
 * 批量复制文件
 * @param src 源文件或文件夹
 * @param dst 目标文件或文件夹
 */
function copyFiles (src, dst) {
    /*文件不存在*/
    if (!fs.existsSync(src)) {
        return logError(`Source file does not exist : ${src}`);
    }
    
    /*单文件 直接复制*/
    if (fs.statSync(src).isFile()) return copyFile(src, dst);
    
    /*若是目录 先创建目标目录*/
    fs.statSync(src).isDirectory() && mkdir(dst);
    
    /*读取文件路径*/
    fs.readdirSync(src).forEach(file => {
        let srcPath = path.resolve(src, file);
        let dstPath = path.resolve(dst, file);
        
        /*文件类型*/
        let fileStat = fs.statSync(srcPath);
        
        /*文件 或 符号连接*/
        if (fileStat.isFile() || fileStat.isSymbolicLink()) {
            return copyFile(srcPath, dstPath)
                ? logInfo(`Copy file successfully : ${dstPath}`)
                : logError(`Failed to copy file : ${dstPath}`);
        }
        
        /*目录*/
        if (fileStat.isDirectory()) {
            if (!mkdir(dstPath)) {
                return logError(`Failed to create directory : ${dstPath}`);
            }
            
            logInfo(`Directory created successfully : ${dstPath}`);
            return copyFiles(srcPath, dstPath);
        }
        
        /*其他文件*/
        return logError(`Unknown file type : ${srcPath}`);
    });
}

/**
 * 复制文件
 * @param src
 * @param dst
 * @returns {boolean}
 */
function copyFile (src, dst) {
    try {
        fs.copyFileSync(src, dst);
    }
    catch (e) {
        logError(e.message);
        return false;
    }
    return true;
}

/**
 * 递归创建目录
 * @param dirPath
 * @returns {boolean}
 */
function mkdir (dirPath) {
    if (fs.existsSync(dirPath)) return true;
    fs.mkdirSync(dirPath, { recursive: true });
    return fs.existsSync(dirPath);
}

/**
 * 信息日志
 * @param msg
 */
function logInfo (msg) {
    logger ? logger.info(msg) : console.debug(`[INFO] ${msg}`);
    return;
}

/**
 * 错误日志
 * @param msg
 */
function logError (msg) {
    logger ? logger.error(msg) : console.error(`[ERROR] ${msg}`);
    return;
}

/**
 * 导出
 * @type {{copyFile: ((function(*=, *=): boolean)|*), requireLogger: requireLogger, copyFiles: ((function(*=, *=): (void|undefined))|*), unrequireLogger: unrequireLogger, mkdir: ((function(*=): boolean)|*), delFiles: ((function(*=): (void))|*)}}
 */
module.exports = {
    requireLogger,
    unrequireLogger,
    delFiles,
    copyFiles,
    copyFile,
    mkdir
};
